﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jbe.TestSuite.Infrastructure.Interface;
using System.Windows.Media;
using System.ComponentModel;
using System.IO;
using Microsoft.Practices.Composite.Presentation.Commands;
using Jbe.TestSuite.Repl.Domain;
using Jbe.Composite.Extensions;
using System.Windows;
using System.Reflection;
using System.Windows.Documents;
using Jbe.TestSuite.Repl.Properties;
using ICSharpCode.AvalonEdit.Document;
using System.Windows.Input;

namespace Jbe.TestSuite.Repl.Applications
{
    internal class ReplPresentationModel : PresentationModel<IReplView>, IHeaderInfoProvider
    {
        private static readonly PropertyInfo HeaderInfoProperty = TypeManager.GetProperty<ReplPresentationModel>(x => x.HeaderInfo);


        private readonly ReplDocument document;


        public ReplPresentationModel(IReplView view, ReplDocument document)
            : base(view)
        {
            this.outputDocument = new TextDocument();
            this.inputDocument = new TextDocument();
            this.document = document;
            PropertyChangedEventManager.AddListener(document, this, "");
            this.outputDocument.Text = "hello world";
            this.evalCommand = new DelegateCommand(Evaluate);
        }


        public ReplDocument Document { get { return document; } }

        public string HeaderInfo
        {
            get { return Path.GetFileName(document.FileName) ?? string.Format(Resources.DocumentTemplate, 1); }
        }

        public ImageSource HeaderIcon
        {
            get { return ResourceService.CreateBitmapSource(Resources.TextDoc.ToBitmap()); }
        }


        protected override void ReceiveWeakEvent(Type managerType, object sender, EventArgs e, ref bool handled)
        {
            base.ReceiveWeakEvent(managerType, sender, e, ref handled);

            if (managerType == typeof(PropertyChangedEventManager) && sender == document)
            {
                DocumentPropertyChanged(sender, (PropertyChangedEventArgs)e);
                handled = true;
            }
        }

        private void DocumentPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "FileName") { RaisePropertyChanged(HeaderInfoProperty); }
        }


        #region TextContent
        TextDocument outputDocument;

        /// <summary>
        /// This property wraps the document class provided by AvalonEdit. The actual text is inside
        /// the document and can be accessed at save, load or other processing times.
        /// 
        /// The Text property itself cannot be bound in AvalonEdit since binding this would result
        /// in updating the text (via binding) each time a user enters a key on the keyboard
        /// (which would be a design error resulting in huge performance problems)
        /// </summary>
        public TextDocument OutputDocument
        {
            get { return outputDocument; }
            set
            {
                if (outputDocument != value)
                {
                    outputDocument = value;
                    RaisePropertyChanged("OutputDocument");
                }
            }
        }
        #endregion

        #region TextContent
        TextDocument inputDocument;

        /// <summary>
        /// This property wraps the document class provided by AvalonEdit. The actual text is inside
        /// the document and can be accessed at save, load or other processing times.
        /// 
        /// The Text property itself cannot be bound in AvalonEdit since binding this would result
        /// in updating the text (via binding) each time a user enters a key on the keyboard
        /// (which would be a design error resulting in huge performance problems)
        /// </summary>
        public TextDocument InputDocument
        {
            get { return inputDocument; }
            set
            {
                if (inputDocument != value)
                {
                    inputDocument = value;
                    RaisePropertyChanged("InputDocument");
                }
            }
        }
        #endregion

        private readonly DelegateCommand evalCommand;

        private void Evaluate()
        {
            this.outputDocument.Insert(1, "hhh");
        }

        public ICommand EvalCommand { get { return evalCommand; } }
    }
}
